package il.technion.cs236369.webserver;

import java.io.IOException;
import java.util.HashMap;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;

import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;


/**
 * This class stores the mappings for the MIME-type/servlets
 *
 */
public class Mappings 
{
	public HashMap<String,String> extensionToClass = new HashMap<String,String>();
	public HashMap<String,String> servlets = new HashMap<String,String>();
	
	/**
	 * Parses the config file and fills webservers fields accordingly
	 * @throws ParserConfigurationException, SAXException, IOException, XPathExpressionException
	 * 
	 */
	public void parseServlets() throws ParserConfigurationException, 
										SAXException, IOException, 
										XPathExpressionException 
	{
		DocumentBuilderFactory docFactory = DocumentBuilderFactory.newInstance();
		docFactory.setNamespaceAware(true);
		DocumentBuilder builder = docFactory.newDocumentBuilder();
		Document doc = builder.parse("config.xml");
		
		XPathFactory xpathFactory = XPathFactory.newInstance();
		XPath xpath = xpathFactory.newXPath();
		
		NodeList nl = (NodeList)xpath.compile("//simple-servlet").evaluate(doc, XPathConstants.NODESET);
		String servletClass = nl.item(0).getAttributes().getNamedItem("class").getNodeValue();

		// map every servlet path to servlet name
		for (int i = 0; i < nl.getLength(); ++i) 
		{
			String extension = xpath.compile("./mapping").evaluate(nl.item(i));
			servlets.put(extension, servletClass);
		}
		
		nl = (NodeList) xpath.compile("//mime-mapping").evaluate(doc, XPathConstants.NODESET);
		for (int i=0; i < nl.getLength(); ++i) 
		{
			String path = xpath.compile("./extension[1]").evaluate(nl.item(i));
			String extension = xpath.compile("./mime-type[1]").evaluate(nl.item(i));
			extensionToClass.put(path, extension);
		}
		
	}

	/**
	 * Returns the mime type associated with the given extension
	 * @param ext
	 * @return
	 */
	public String getMimeType(String ext) 
	{
		return extensionToClass.get(ext);
	}
	
	/**
	 * Gets the type of the servlet
	 * @param path the url extension for the servlet
	 * @return the name of the servlet class whose path is given,
	 * 		null if no such path exists
	 */
	public String getServletType(String path) 
	{
		return servlets.get(path);
	}

	public String getContentType(ExtendedHttpRequest request)
	{
		String type = "";
		String[] splittedPath = request.GetPath().split("\\.");
	
		if (splittedPath.length > 1) 
		{
			type = splittedPath[splittedPath.length-1];
		}
		
		//find mime type
		String contentType = getMimeType(type);
		
		if (contentType==null)
		{
			contentType="";
		}
		
		return contentType;
	}
	
	/**
	 * returns the servlet path in the request's path
	 * @param request
	 * @return the servlet path or empty string if non exist
	 */
	public static String getServletPath(ExtendedHttpRequest request)
	{
		String type = "";
		String[] splitPath = request.GetPath().split("\\\\");
		
		if (splitPath.length > 1) 
		{
			type = splitPath[splitPath.length-1];
		}
		else if (splitPath[0].startsWith("/"))
		{
			type = splitPath[0];
		}
		
		return type;
	}
	
}
